# -*- coding: utf-8 -*-
'''
    :file: http.py
    :author: -Farmer
    :url: https://blog.farmer233.top
    :date: 2021/04/27 15:17:24
'''

class HttpRequest():
    def __init__(self, request_message:str) -> None:
        method, path, http_version, headers, args, body = self.parse_data(request_message)
        self.method = method
        self.path = path
        self.http_version = http_version
        self.headers = headers
        self.args = args
        self.body = body
        # (body)

    def parse_data(self, data:str):
        # 切割报文头和报文主体
        headers, body = data.split('\r\n\r\n', 1)
        # 解析报文头
        method, path, http_version, headers, args = self._parse_header(headers=headers)
        # 解析报文主体
        
        return method, path, http_version, headers, args, body


    def _parse_header(self, headers:str):
        # 拆分请求行和请求首部
        request_line, request_header = headers.split('\r\n', 1)

        # 解析请求行
        method, path, http_version = request_line.split(' ')

        # 解析arg参数
        path, args = self._parse_path(path)

        # 解析请求首部，构建键值对headers
        headers = {}
        for header in request_header.split('\r\n'):
            k, v = header.split(': ', 1)
            headers[k] = v

        return method, path, http_version, headers, args
    
    @staticmethod
    def _parse_path(path:str):
        args = {}
        # 请求路径和 GET 请求参数格式: /index?edit=1&content=text
        if '?' not in path:
            path, query = path, ''
        else:
            path, query = path.split('?', 1)
            for q in query.split('&'):
                k, v = q.split('=', 1)
                args[k] = v
        return path, args


class HttpResponse():
    # 通过状态码获取首行内容
    reason_phrase = {
        200: "ok",
        302: 'FOUND',
        404: 'PAGE NOT FOUND',
        405: 'METHOD NOT ALLOWED',
    }

    def __init__(self, body, headers=None, status=200) -> None:
        """
        @description: 初始化方法
        ---------
        @param: 
            body: 响应体
            headers: 响应头
            status: 状态码
        -------
        @Returns: None
        -------
        """
        # 默认响应头
        _headers = {
            'Content-Type': 'text/html; charset=utf-8',
            # 'Content-Length': len(body)
        }

        if headers is not None:
            _headers.update(headers)

        self.headers = _headers 
        self.body = body
        self.status = status

    def __bytes__(self):
        ''' 构建响应报文 '''
        # 状态首部
        header = f"HTTP/1.1 {self.status} {self.reason_phrase.get(self.status, '')}\r\n"

        # 响应报文头
        header += "".join(f"{k}: {v}\r\n" for k, v in self.headers.items())

        # 响应体
        if isinstance(self.body, str):
            response_message = f'{header}\r\n{self.body}'.encode('utf-8')
        else:
            response_message = f'{header}\r\n'.encode('utf-8') + self.body
        return response_message